home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP07.ZIP / CHAP07 / SCHMOO / SCHMOO.CPP < prev    next >
C/C++ Source or Header  |  1993-06-15  |  15KB  |  658 lines

  1. /*
  2.  * SCHMOO.CPP
  3.  * Chapter 7 Modifications
  4.  * WinMain and CSchmooFrame implementations.
  5.  *
  6.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  7.  *
  8.  * Kraig Brockschmidt, Software Design Engineer
  9.  * Microsoft Systems Developer Relations
  10.  *
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #define INITGUIDS
  17. #include "schmoo.h"
  18.  
  19.  
  20.  
  21.  
  22. /*
  23.  * WinMain
  24.  *
  25.  * Purpose:
  26.  *  Main entry point of application.   Should register the app class
  27.  *  if a previous instance has not done so and do any other one-time
  28.  *  initializations.
  29.  */
  30.  
  31. int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR pszCmdLine, int nCmdShow)
  32.     {
  33.     LPCSchmooFrame  pFR;
  34.     FRAMEINIT       fi;
  35.     WPARAM          wRet;
  36.  
  37.    #ifndef WIN32
  38.     SetMessageQueue(96);
  39.    #endif
  40.  
  41.     //Attempt to allocate and initialize the application
  42.     pFR=new CSchmooFrame(hInst, hPrev, pszCmdLine, nCmdShow);
  43.  
  44.     fi.idsMin=IDS_FRAMEMIN;
  45.     fi.idsMax=IDS_FRAMEMAX;
  46.     fi.idsStatMin=IDS_STATMESSAGEMIN;
  47.     fi.idsStatMax=IDS_STATMESSAGEMAX;
  48.     fi.idStatMenuMin=ID_MENUFILE;
  49.     fi.idStatMenuMax=ID_MENUHELP;
  50.     fi.iPosWindowMenu=WINDOW_MENU;
  51.     fi.cMenus=CMENUS;
  52.  
  53.     //If we can initialize pFR, start chugging messages
  54.     if (pFR->FInit(&fi))
  55.         wRet=pFR->MessageLoop();
  56.  
  57.     delete pFR;
  58.     return wRet;
  59.     }
  60.  
  61.  
  62.  
  63.  
  64. /*
  65.  * CSchmooFrame::CSchmooFrame
  66.  * CSchmooFrame::~CSchmooFrame
  67.  *
  68.  * Constructor Parameters:
  69.  *  hInst           HINSTANCE from WinMain
  70.  *  hInstPrev       HINSTANCE from WinMain
  71.  *  pszCmdLine      LPSTR from WinMain
  72.  *  nCmdShow        int from WInMain
  73.  */
  74.  
  75. CSchmooFrame::CSchmooFrame(HINSTANCE hInst, HINSTANCE hInstPrev
  76.     , LPSTR pszCmdLine, int nCmdShow)
  77.     : CFrame(hInst, hInstPrev, pszCmdLine, nCmdShow)
  78.     {
  79.     UINT        i;
  80.  
  81.     for (i=0; i<5; i++)
  82.         m_hBmpLines[i]=NULL;
  83.  
  84.     m_fInitialized=FALSE;
  85.     return;
  86.     }
  87.  
  88.  
  89. CSchmooFrame::~CSchmooFrame(void)
  90.     {
  91.     UINT            i;
  92.  
  93.     for (i=0; i<5; i++)
  94.         DeleteObject(m_hBmpLines[i]);
  95.  
  96.     //CHAPTER7MOD
  97.     OleFlushClipboard();
  98.     //End CHAPTER7MOD
  99.  
  100.     if (m_fInitialized)
  101.         OleUninitialize();
  102.  
  103.     return;
  104.     }
  105.  
  106.  
  107.  
  108.  
  109. /*
  110.  * CSchmooFrame::FInit
  111.  *
  112.  * Purpose:
  113.  *  Call CoInitialize then calling down into the base class
  114.  *  initialization.
  115.  *
  116.  * Parameters:
  117.  *  pFI             LPFRAMEINIT containing initialization parameters.
  118.  *
  119.  * Return Value:
  120.  *  BOOL            TRUE if initialization succeeded, FALSE otherwise.
  121.  */
  122.  
  123. BOOL CSchmooFrame::FInit(LPFRAMEINIT pFI)
  124.     {
  125.     DWORD       dwVer;
  126.  
  127.     //We need OLE versions of Initialize for Clipboard
  128.     dwVer=OleBuildVersion();
  129.  
  130.     if (rmm!=HIWORD(dwVer))
  131.         return FALSE;
  132.  
  133.     if (FAILED(OleInitialize(NULL)))
  134.         return FALSE;
  135.  
  136.     m_fInitialized=TRUE;
  137.  
  138.     return CFrame::FInit(pFI);
  139.     }
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146. /*
  147.  * CSchmooFrame::CreateCClient
  148.  *
  149.  * Purpose:
  150.  *  Constructs a new client specific to the application.
  151.  *
  152.  * Parameters:
  153.  *  None
  154.  *
  155.  * Return Value:
  156.  *  LPCClient       Pointer to the new client object.
  157.  */
  158.  
  159. LPCClient CSchmooFrame::CreateCClient(void)
  160.     {
  161.     return (LPCClient)(new CSchmooClient(m_hInst));
  162.     }
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171. /*
  172.  * CSchmooFrame::FRegisterAllClasses
  173.  *
  174.  * Purpose:
  175.  *  Registers all classes used in this application.
  176.  *
  177.  * Parameters:
  178.  *  None
  179.  *
  180.  * Return Value:
  181.  *  BOOL            TRUE if registration succeeded, FALSE otherwise.
  182.  */
  183.  
  184. BOOL CSchmooFrame::FRegisterAllClasses(void)
  185.     {
  186.     WNDCLASS        wc;
  187.  
  188.     //First let the standard frame do its thing
  189.     if (!CFrame::FRegisterAllClasses())
  190.         return FALSE;
  191.  
  192.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  193.     wc.hInstance     = m_hInst;
  194.     wc.cbClsExtra    = 0;
  195.     wc.lpfnWndProc   = PolylineWndProc;
  196.     wc.cbWndExtra    = CBPOLYLINEWNDEXTRA;
  197.     wc.hIcon         = NULL;
  198.     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  199.     wc.hbrBackground = NULL;
  200.     wc.lpszMenuName  = NULL;
  201.     wc.lpszClassName = SZCLASSPOLYLINE;
  202.  
  203.     if (!RegisterClass(&wc))
  204.         return FALSE;
  205.  
  206.     return TRUE;
  207.     }
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214. /*
  215.  * CSchmooFrame::FPreShowInit
  216.  *
  217.  * Purpose:
  218.  *  Called from FInit before intially showing the window.  We do whatever
  219.  *  else we want here, modifying nCmdShow as necessary which affects
  220.  *  ShowWindow in FInit.
  221.  *
  222.  * Parameters:
  223.  *  None
  224.  *
  225.  * Return Value:
  226.  *  BOOL            TRUE if this initialization succeeded, FALSE otherwise.
  227.  */
  228.  
  229. BOOL CSchmooFrame::FPreShowInit(void)
  230.     {
  231.     CreateLineMenu();
  232.     CheckLineSelection(IDM_LINESOLID);
  233.     m_pGB->Check(IDM_LINESOLID, TRUE);
  234.     return TRUE;
  235.     }
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242. /*
  243.  * CSchmooFrame::CreateLineMenu
  244.  *
  245.  * Purpose:
  246.  *  Initializes the bitmaps used to create the Line menu and replaces
  247.  *  the text items defined in the application resources with these
  248.  *  bitmaps.  Note that the contents of m_hBmpLines must be cleaned
  249.  *  up when the application terminates.
  250.  *
  251.  * Parameters:
  252.  *  None
  253.  *
  254.  * Return Value:
  255.  *  None
  256.  */
  257.  
  258. void CSchmooFrame::CreateLineMenu(void)
  259.     {
  260.     HMENU       hMenu;
  261.     HDC         hDC, hMemDC;
  262.     HPEN        hPen;
  263.     HGDIOBJ     hObj;
  264.     TEXTMETRIC  tm;
  265.     UINT        i, cx, cy;
  266.  
  267.  
  268.     hMenu=GetSubMenu(GetMenu(m_hWnd), 3);   //Line menu.
  269.     hDC=GetDC(m_hWnd);
  270.  
  271.     //Create each line in a menu item 8 chars wide, one char high.
  272.     GetTextMetrics(hDC, &tm);
  273.     cx=tm.tmAveCharWidth*8;
  274.     cy=tm.tmHeight;
  275.  
  276.     //Create a memory DC in which to draw lines, and bitmaps for each line.
  277.     hMemDC=CreateCompatibleDC(hDC);
  278.     ReleaseDC(m_hWnd, hDC);
  279.  
  280.     for (i=0; i<5; i++)
  281.         {
  282.         m_hBmpLines[i]=CreateCompatibleBitmap(hMemDC, cx, cy);
  283.         SelectObject(hMemDC, m_hBmpLines[i]);
  284.  
  285.         PatBlt(hMemDC, 0, 0, cx, cy, WHITENESS);
  286.  
  287.         hPen=CreatePen(i, 1, 0L);           //i==line style like PS_SOLID
  288.         hObj=SelectObject(hMemDC, hPen);
  289.  
  290.         MoveTo(hMemDC, 0,  cy/2);
  291.         LineTo(hMemDC, cx, cy/2);
  292.  
  293.         ModifyMenu(hMenu, IDM_LINEMIN+i, MF_BYCOMMAND | MF_BITMAP
  294.             , IDM_LINEMIN+i, (LPCSTR)MAKELONG(m_hBmpLines[i], 0));
  295.  
  296.         SelectObject(hMemDC, hObj);
  297.         DeleteObject(hPen);
  298.         }
  299.  
  300.     CheckMenuItem(hMenu, IDM_LINESOLID, MF_CHECKED);
  301.     DeleteDC(hMemDC);
  302.  
  303.     return;
  304.     }
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314. /*
  315.  * CSchmooFrame::CreateGizmos
  316.  *
  317.  * Purpose:
  318.  *  Procedure to create all the necessary gizmobar buttons.
  319.  *
  320.  * Parameters:
  321.  *  None
  322.  *
  323.  * Return Value:
  324.  *  UINT            Number of gizmos added to the bar.
  325.  */
  326.  
  327. UINT CSchmooFrame::CreateGizmos(void)
  328.     {
  329.     UINT            iLast;
  330.     UINT            uState=GIZMO_NORMAL;
  331.     UINT            utCmd =GIZMOTYPE_BUTTONCOMMAND;
  332.     UINT            utEx  =GIZMOTYPE_BUTTONATTRIBUTEEX;
  333.  
  334.     //Insert the standard ones.
  335.     iLast=CFrame::CreateGizmos();
  336.  
  337.     //Insert File Import in the 5th position and account for it in iLast.
  338.     m_pGB->Add(utCmd, 4, IDM_FILEIMPORT, m_dxB, m_dyB, NULL, m_hBmp, 2, uState);
  339.     iLast++;
  340.  
  341.     //Separator
  342.     m_pGB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB, NULL, NULL, 0, uState);
  343.  
  344.     //For the Background bitmap, preserve our use of black (part of the image)
  345.     m_pGB->Add(utCmd, iLast++, IDM_COLORBACKGROUND, m_dxB, m_dyB, NULL, m_hBmp, 3
  346.                , GIZMO_NORMAL | PRESERVE_BLACK);
  347.  
  348.     m_pGB->Add(utCmd, iLast++, IDM_COLORLINE, m_dxB, m_dyB, NULL, m_hBmp, 4, uState);
  349.  
  350.     //Separator
  351.     m_pGB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB, NULL, NULL, 0, uState);
  352.  
  353.     //Line styles.
  354.     m_pGB->Add(utEx, iLast++, IDM_LINESOLID,      m_dxB, m_dyB, NULL, m_hBmp, 5, uState);
  355.     m_pGB->Add(utEx, iLast++, IDM_LINEDASH,       m_dxB, m_dyB, NULL, m_hBmp, 6, uState);
  356.     m_pGB->Add(utEx, iLast++, IDM_LINEDOT,        m_dxB, m_dyB, NULL, m_hBmp, 7, uState);
  357.     m_pGB->Add(utEx, iLast++, IDM_LINEDASHDOT,    m_dxB, m_dyB, NULL, m_hBmp, 8, uState);
  358.     m_pGB->Add(utEx, iLast++, IDM_LINEDASHDOTDOT, m_dxB, m_dyB, NULL, m_hBmp, 9, uState);
  359.  
  360.     return iLast;
  361.     }
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370. /*
  371.  * CSchmooFrame::OnCommand
  372.  *
  373.  * Purpose:
  374.  *  WM_COMMAND handler for the Schmoo frame window that just processes
  375.  *  the line menu and the color menu leaving the CFrame to do everything
  376.  *  else.
  377.  *
  378.  * Parameters:
  379.  *  hWnd            HWND of the frame window.
  380.  *  wParam          WPARAM of the message.
  381.  *  lParam          LPARAM of the message.
  382.  *
  383.  * Return Value:
  384.  *  LRESULT         Return value for the message.
  385.  */
  386.  
  387. LRESULT CSchmooFrame::OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
  388.     {
  389.     LPCSchmooDoc    pDoc;
  390.     char            szFile[CCHPATHMAX];
  391.     BOOL            fOK;
  392.     UINT            i, uTemp;
  393.     COLORREF        rgColors[16];
  394.     CHOOSECOLOR     cc;
  395.  
  396.     COMMANDPARAMS(wID, wCode, hWndMsg);
  397.  
  398.     /*
  399.      * Don't bother with anything during first initialization,
  400.      * skipping many GizmoBar notifications.
  401.      */
  402.     if (m_fInit)
  403.         return 0L;
  404.  
  405.     pDoc=(LPCSchmooDoc)m_pCL->ActiveDocument();
  406.  
  407.     /*
  408.      * Check for the line style commands which are IDM_LINEMIN+<style>.
  409.      * We handle this by changing the menu and toolbar, then we pass
  410.      * it to the document for real processing.
  411.      */
  412.     if (NULL!=pDoc && IDM_LINEMIN <= wID && IDM_LINEMAX >=wID)
  413.         {
  414.         CheckLineSelection(wID);
  415.         pDoc->LineStyleSet(wID-IDM_LINEMIN);
  416.         return 0L;
  417.         }
  418.  
  419.     switch (wID)
  420.         {
  421.         case IDM_FILEIMPORT:
  422.             szFile[0]=0;
  423.             fOK=FSaveOpenDialog(szFile, CCHPATHMAX, IDS_FILEIMPORT, TRUE, &i);
  424.  
  425.             if (fOK)
  426.                 {
  427.                 uTemp=pDoc->ULoad(FALSE, szFile);
  428.                 pDoc->ErrorMessage(uTemp);
  429.                 }
  430.  
  431.             return (LRESULT)fOK;
  432.  
  433.  
  434.         case IDM_COLORBACKGROUND:
  435.         case IDM_COLORLINE:
  436.             //Invoke the color chooser for either color
  437.             uTemp=(IDM_COLORBACKGROUND==wID)
  438.                 ? DOCCOLOR_BACKGROUND : DOCCOLOR_LINE;
  439.  
  440.             for (i=0; i<16; i++)
  441.                 rgColors[i]=RGB(0, 0, i*16);
  442.  
  443.             memset(&cc, 0, sizeof(CHOOSECOLOR));
  444.             cc.lStructSize=sizeof(CHOOSECOLOR);
  445.             cc.lpCustColors=rgColors;
  446.             cc.hwndOwner=hWnd;
  447.             cc.Flags=CC_RGBINIT;
  448.             cc.rgbResult=pDoc->ColorGet(uTemp);
  449.  
  450.             if (ChooseColor(&cc))
  451.                 pDoc->ColorSet(uTemp, cc.rgbResult);
  452.  
  453.             break;
  454.  
  455.  
  456.         default:
  457.            CFrame::OnCommand(hWnd, wParam, lParam);
  458.         }
  459.  
  460.     return 0L;
  461.     }
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468. /*
  469.  * CSchmooFrame::OnDocumentDataChange
  470.  *
  471.  * Purpose:
  472.  *  Update the Line menu and GizmoBar if the style in the data changes.
  473.  *
  474.  * Parameters:
  475.  *  pDoc            LPCDocument notifying the sink.
  476.  *
  477.  * Return Value:
  478.  *  None
  479.  */
  480.  
  481. void CSchmooFrame::OnDocumentDataChange(LPCDocument pDoc)
  482.     {
  483.     CheckLineSelection(IDM_LINEMIN+((LPCSchmooDoc)pDoc)->LineStyleGet());
  484.     return;
  485.     }
  486.  
  487.  
  488.  
  489.  
  490. /*
  491.  * CSchmooFrame::OnDocumentActivate
  492.  *
  493.  * Purpose:
  494.  *  Informs us that document activation changed, so update the UI for
  495.  *  that new document.
  496.  *
  497.  * Parameters:
  498.  *  pDoc            LPCDocument notifying the sink.
  499.  *
  500.  * Return Value:
  501.  *  None
  502.  */
  503.  
  504. void CSchmooFrame::OnDocumentActivate(LPCDocument pDoc)
  505.     {
  506.     CheckLineSelection(IDM_LINEMIN+((LPCSchmooDoc)pDoc)->LineStyleGet());
  507.     return;
  508.     }
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516. /*
  517.  * CSchmooFrame::UpdateMenus
  518.  *
  519.  * Purpose:
  520.  *  Handles the WM_INITMENU message for the frame window.  Depending
  521.  *  on the existence of an active window, menu items are selectively
  522.  *  enabled and disabled.
  523.  *
  524.  * Parameters:
  525.  *  hMenu           HMENU of the menu to intialize
  526.  *  iMenu           UINT position of the menu.
  527.  *
  528.  * Return Value:
  529.  *  None
  530.  */
  531.  
  532. void CSchmooFrame::UpdateMenus(HMENU hMenu, UINT iMenu)
  533.     {
  534.     LPCDocument pDoc;
  535.     BOOL        fOK=FALSE;
  536.     BOOL        fCallDefault=TRUE;
  537.     UINT        i;
  538.     UINT        uTemp;
  539.     UINT        uTempE;
  540.     UINT        uTempD;
  541.  
  542.     pDoc=m_pCL->ActiveDocument();
  543.  
  544.     uTempE=MF_ENABLED | MF_BYCOMMAND;
  545.     uTempD=MF_DISABLED | MF_GRAYED | MF_BYCOMMAND;
  546.     uTemp=((NULL!=pDoc) ? uTempE : uTempD);
  547.  
  548.     //File menu:  If there is no current document window, disable Import.
  549.     if (m_phMenu[0]==hMenu)
  550.         EnableMenuItem(hMenu, IDM_FILEIMPORT, uTemp);
  551.  
  552.     //Color menu:  no document, no commands
  553.     if (m_phMenu[2]==hMenu)
  554.         {
  555.         EnableMenuItem(hMenu, IDM_COLORBACKGROUND, uTemp);
  556.         EnableMenuItem(hMenu, IDM_COLORLINE,       uTemp);
  557.         fCallDefault=FALSE;
  558.         }
  559.  
  560.     //Line menu:  no document, no commands
  561.     if (m_phMenu[3]==hMenu)
  562.         {
  563.         for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  564.             EnableMenuItem(hMenu, i, uTemp);
  565.  
  566.         fCallDefault=FALSE;
  567.         }
  568.  
  569.     if (fCallDefault)
  570.         CFrame::UpdateMenus(hMenu, iMenu);
  571.  
  572.     return;
  573.     }
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580. /*
  581.  * CSchmooFrame::UpdateGizmos
  582.  *
  583.  * Purpose:
  584.  *  Enables and disables gizmos depending on whether we have
  585.  *  a document or not.
  586.  *
  587.  * Parameters:
  588.  *  None
  589.  *
  590.  * Return Value:
  591.  *  None
  592.  */
  593.  
  594. void CSchmooFrame::UpdateGizmos(void)
  595.     {
  596.     LPCDocument pDoc;
  597.     BOOL        fEnable;
  598.     UINT        i;
  599.  
  600.     //Let the default hack on its gizmos.
  601.     CFrame::UpdateGizmos();
  602.  
  603.     pDoc=m_pCL->ActiveDocument();
  604.     fEnable=(NULL!=pDoc);
  605.  
  606.     //No document, disable just about everything
  607.     m_pGB->Enable(IDM_FILEIMPORT, fEnable);
  608.  
  609.     m_pGB->Enable(IDM_COLORBACKGROUND, fEnable);
  610.     m_pGB->Enable(IDM_COLORLINE,       fEnable);
  611.  
  612.     for (i=IDM_LINEMIN; i <= IDM_LINEMAX; i++)
  613.         m_pGB->Enable(i, fEnable);
  614.  
  615.     return;
  616.     }
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623. /*
  624.  * CSchmooFrame::CheckLineSelection
  625.  *
  626.  * Purpose:
  627.  *  Maintains the bitmap menu and the gizmos for the line selection.  Both
  628.  *  are mutially exclusive option lists where a selection in one has to
  629.  *  affect the other.
  630.  *
  631.  * Parameters:
  632.  *  uID             UINT ID of the item to be selected
  633.  *
  634.  * Return Value:
  635.  *  None
  636.  */
  637.  
  638. void CSchmooFrame::CheckLineSelection(UINT uID)
  639.     {
  640.     UINT        i;
  641.     HMENU       hMenu;
  642.     LPCDocument pDoc;
  643.  
  644.     hMenu=GetMenu(m_hWnd);
  645.  
  646.     //Uncheck all lines initially.
  647.     for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  648.         CheckMenuItem(hMenu, i, MF_UNCHECKED | MF_BYCOMMAND);
  649.  
  650.     CheckMenuItem(hMenu, uID, MF_CHECKED | MF_BYCOMMAND);
  651.     m_pGB->Check(uID, TRUE);
  652.  
  653.     pDoc=m_pCL->ActiveDocument();
  654.     m_pGB->Enable(uID, (NULL!=pDoc));
  655.  
  656.     return;
  657.     }
  658.